package com.jsu.exhibitor.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jsu.exhibitor.mapper.ExhibitorMapper;
import com.jsu.exhibitor.mapper.ExpertMapper;
import com.jsu.exhibitor.service.ExhibitorService;
import com.jsu.exhibitor.service.ExpertService;
import lombok.extern.slf4j.Slf4j;
import org.example.model.common.dtos.ResponseResult;
import org.example.model.common.enums.RedisCodeEnum;
import org.example.model.common.enums.WebHttpCodeEnum;
import org.example.model.exhibitor.pojos.Exhibitor;
import org.example.model.exhibitor.pojos.Expert;
import org.example.model.information.pojo.News;
import org.example.utils.common.FileTools;
import org.example.utils.common.IdsUtils;
import org.example.utils.common.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;

@Service
@Slf4j
public class ExpertServiceImpl extends ServiceImpl<ExpertMapper, Expert> implements ExpertService {
    @Autowired
    private StringRedisTemplate redisCache;

    private static final ObjectMapper mapper = new ObjectMapper();

    /**
     * 修改专家信息
     * @param expert
     * @return
     */
    @Override
    public ResponseResult updateExpert(Expert expert) {
        String key = RedisCodeEnum.EXPERT.getMsg()+expert.getPkId();
        redisCache.opsForValue().getOperations().delete(key);
        String json = null;
        try {
            json = mapper.writeValueAsString(expert);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        redisCache.opsForValue().set(key,json);
        int count = getBaseMapper().updateById(expert);
        if (count<=0) {
            return ResponseResult.errorResult(WebHttpCodeEnum.FAIL,"修改失败");
        }
        return ResponseResult.okResult(200,"修改成功");
    }

    /**
     * 删除专家信息
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteExpert(Integer id) {
        String key = RedisCodeEnum.EXHIBITOR.getMsg()+id;
        redisCache.opsForValue().getOperations().delete(key);
        int count = getBaseMapper().deleteById(id);
        if (count<=0) {
            return ResponseResult.errorResult(WebHttpCodeEnum.FAIL,"删除失败");
        }
        return ResponseResult.okResult(200,"删除成功");
    }

    /**
     * 新增专家信息
     *
     * @param expert
     * @return
     */
    @Override
    public ResponseResult addExpert(Expert expert) {
        expert.setPkId(Integer.valueOf(IdsUtils.creatID()));
        String key = RedisCodeEnum.EXPERT.getMsg()+expert.getPkId();
        String json = null;
        try {
            json = mapper.writeValueAsString(expert);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        redisCache.opsForValue().set(key,json);
        log.info("新增专家信息：{}",expert);
        int count = getBaseMapper().insert(expert);
        if (count<=0) {
            return ResponseResult.errorResult(WebHttpCodeEnum.FAIL,"新增失败");
        }
        return ResponseResult.okResult(200,"新增成功");
    }

    /**
     * 获取专家信息
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult getExpert(Integer id) {
        //从redis中获取信息
        String key = RedisCodeEnum.EXPERT.getMsg()+id;
        String json = redisCache.opsForValue().get(key);
        Expert expert = null;
        try {
            expert = mapper.readValue(json, Expert.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if(!Objects.isNull(expert)){
            return ResponseResult.okResult(expert);
        }
        //从数据库中获取
        expert = getBaseMapper().selectById(id);
        if(Objects.isNull(expert)){
            return ResponseResult.errorResult(WebHttpCodeEnum.DATA_NOT_EXIST,"没有该专家");
        }
        return ResponseResult.okResult(expert);
    }

    /**
     * 获取所有专家信息
     *
     * @return
     */
    @Override
    public ResponseResult getAllExpert() {
        //从redis中获取展商信息
        List<String> experts = redisCache.opsForList().range(RedisCodeEnum.EXPERT.getMsg(),0,-1);
        List<Expert> expertList = new ArrayList<>();
        if (experts.size()==0) {
            expertList = getBaseMapper().selectList(null);
        }else {
            expertList = new ArrayList<>();
            for (String json:experts) {
                Expert expert = null;
                try {
                    expert = mapper.readValue(json, Expert.class);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                expertList.add(expert);
            }
        }
        if(expertList.size()==0)
            return ResponseResult.errorResult(WebHttpCodeEnum.DATA_NOT_EXIST,"没有专家信息");
        return ResponseResult.okResult(expertList);
    }

    /**
     * 上传文件
     * @param file
     * @return
     */
    @Override
    public ResponseResult uploadExcel(MultipartFile file) {
        if (file.isEmpty()) {
            return ResponseResult.errorResult(WebHttpCodeEnum.DATA_NOT_EXIST,"上传的文件不能为空");
        }
        try {
            File excelFile = File.createTempFile("temp", ".xlsx"); // 创建临时文件
            file.transferTo(excelFile); // 将上传的文件保存到临时文件
            List<Expert> expertList = FileTools.readExcel(excelFile, Expert.class); // 调用读取 Excel 方法
            //批量导入到数据库
            boolean success = saveBatch(expertList);
            //批量存储到redis中
            for (Expert n:expertList) {
                String key = RedisCodeEnum.EXPERT.getMsg()+n.getPkId();
                String json = mapper.writeValueAsString(n);
                redisCache.opsForValue().set(key,json);
            }
            if (success) {
                return ResponseResult.okResult(WebHttpCodeEnum.SUCCESS);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseResult.errorResult(WebHttpCodeEnum.FAIL);
        }
        return ResponseResult.errorResult(WebHttpCodeEnum.FAIL);
    }

    /**
     * 导出文件
     * @param fileName
     * @return
     */
    @Override
    public ResponseResult exportExcel(String fileName) {
        try {
            List<Expert> expertList = getBaseMapper().selectList(null); // 获取要导出的数据集合
            int count = FileTools.writeExcel(fileName, Expert.class, expertList);// 调用写入 Excel 方法
            if(count>0)
                return ResponseResult.okResult(count);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return ResponseResult.errorResult(WebHttpCodeEnum.FAIL,"暂时没有数据");
    }

    /**
     * 搜索专家信息
     *
     * @param keyword
     * @return
     */
    @Override
    public ResponseResult searchExpert(String keyword) {
        List<Expert> expertList = getBaseMapper().searchExpertsByKeyword(keyword);
        if (expertList.size() == 0){
            return ResponseResult.errorResult(WebHttpCodeEnum.DATA_NOT_EXIST,"没有搜索到相关专家信息");
        }
        return ResponseResult.okResult(expertList);
    }


    /**
     * 批量删除专家信息
     *
     * @param ids
     * @return
     */
    @Override
    public ResponseResult deleteExperts(Integer[] ids) {
        List<Integer> expertIds = ids.length>0? Arrays.asList(ids):new ArrayList<>();
        for (Integer id:expertIds) {
            String key = RedisCodeEnum.EXPERT.getMsg() + id;
            redisCache.opsForValue().getOperations().delete(key);
        }
        int count = getBaseMapper().deleteBatchIds(expertIds);
        if (count<=0) {
            return ResponseResult.errorResult(WebHttpCodeEnum.FAIL,"删除失败");
        }
        return ResponseResult.okResult(200,"删除成功");
    }
}
